﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using Acando.Dynamics.CRM.Silverlight.Library.Helper;
using System.Diagnostics;
using Acando.Dynamics.CRM.Silverlight.Library.Interfaces;
using Acando.Dynamics.CRM.Silverlight.Library.CrmSdk;
using System.ServiceModel;
using System.Collections.Generic;


namespace Acando.Dynamics.CRM.Silverlight.Library.Model
{
    public class GenericDataModel : IDataModel
    {
        
        private CrmServiceSoapClient service;        
        private Type EntityType { get; set; }
        private String _organame;

        public GenericDataModel(Type entityType, String organame)
        {
            this.EntityType = entityType;
            this.service = SoapClientFactory.CreateCrmInstanceSilver();
            this._organame = organame;
        }

        #region IDataModel Members

        public string EntityTypeName
        {
            get { return this.EntityType.Name; }
        }

        public void Create(BusinessEntity item)
        {
            WrapperServiceCall.CreateWrapper(this.service, item, this._organame);
            //this.service.CreateAsync(item);
        }

        public void Update(BusinessEntity item)
        {
            WrapperServiceCall.UpdateWrapper(this.service, item, this._organame);
            //this.service.UpdateAsync(item);
        }

        public void Retrieve(Guid id)
        {
            WrapperServiceCall.RetrieveWrapper(this.service, this.EntityTypeName, id, new AllColumns(), this._organame);
            //this.service.RetrieveAsync(this.EntityTypeName, id, new AllColumns());
        }

        public void Request(RetrieveMultipleRequest request)
        {
            request.ReturnDynamicEntities = true;
            
            if(request.Query != null)
                request.Query.EntityName = this.EntityTypeName;

            WrapperServiceCall.ExecuteWrapper(this.service, request, this._organame);
           
        }

        public void Request(QueryBase query)
        {
            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.Query = query;

            this.Request(request);
        }


        public void RetrieveMultiple()
        {
            QueryBase query = new QueryExpression();
            query.EntityName = this.EntityType.Name;
            query.ColumnSet = new AllColumns();

            this.RetrieveMultiple(query);
        }

        public void RetrieveMultiple(QueryBase query)
        {
            query.EntityName = this.EntityType.Name;

            WrapperServiceCall.RetrieveMultipleWrapper(this.service, query, this._organame);
            //this.service.RetrieveMultipleAsync(query);

        }

        public BusinessEntity NewItem()
        {
            return (BusinessEntity)this.EntityType.InvokeMember(this.EntityType.Name, System.Reflection.BindingFlags.CreateInstance, null, null, null);
        }

        public BusinessEntity CopyItem(BusinessEntity item)
        {
            if (item == null)
                return null;
            else
                return SerializationHelper.DeserializeXmlTo<BusinessEntity>(SerializationHelper.SerializeToXml<BusinessEntity>(item));
        }

        # region Events

        public event EventHandler<ExecuteCompletedEventArgs> ExecuteCompleted
        {
            add { this.service.ExecuteCompleted += value; }
            remove {this.service.ExecuteCompleted -= value;}
        }

        public event EventHandler<CreateCompletedEventArgs> Created
        {
            add { this.service.CreateCompleted += value; }
            remove { this.service.CreateCompleted -= value; }
        }

        public event EventHandler<AsyncCompletedEventArgs> Updated
        {
            add { this.service.UpdateCompleted += value; }
            remove { this.service.UpdateCompleted -= value; }
        }

        public event EventHandler<RetrieveMultipleCompletedEventArgs> RetrieveMultipleCompleted
        {
            add { this.service.RetrieveMultipleCompleted += value; }
            remove { this.service.RetrieveMultipleCompleted -= value; }
        }

        public event EventHandler<RetrieveCompletedEventArgs> RetrieveCompleted
        {
            add { this.service.RetrieveCompleted += value; }
            remove { this.service.RetrieveCompleted -= value; }
        }

        # endregion

        #endregion
    }
}
